Manipulating List Cells
In addition to theLSetCell
procedure, the List Manager provides four procedures,LAddToCell
,LClrCell
,LGetCellDataLocation
, andLGetCell
, that allow you to manipulate cell item data. You can use theLAddToCell
procedure to append data to list items and theLClrCell
procedure to remove all data from a list item. TheLGetCellDataLocation
procedure indicates the location of the beginning of a cell's data within thecells
field of the list record as well as the length of that data, and theLGetCell
procedure copies a cell's data to a buffer that your application specifies.Listing 4-11 illustrates the use of
LClrCell
to clear the data from all cells in a list.Listing 4-11 Clearing all cell data
PROCEDURE MyClearAllCellData (myList: ListHandle); VAR aCell: Cell; BEGIN SetPt(aCell, 0, 0); REPEAT LClrCell(aCell, myList); UNTIL NOT LNextCell(TRUE, TRUE, aCell, myList); END;BecauseLClrCell
simply does nothing if passed a cell not in the list, theMyClearAllCellData
procedure defined in Listing 4-11 will not crash when attempting to clear the first cell even if there are no cells in the list.Listing 4-12 uses the
LGetCell
procedure to return the data of a specific cell.Listing 4-12 Getting a copy of the data of a cell
PROCEDURE MyGetCellData (dataPtr: Ptr; VAR dataLen: Integer; aCell: Cell; myList: ListHandle); BEGIN LGetCell(dataPtr, dataLen, aCell, myList); END;TheLGetCell
procedure copies cell data to memory beginning at the location specified bydataPtr
. It copies only the number of bytes specified by the value passed in thedataLen
parameter; it returns in that parameter the number of bytes actually copied.Because the
LGetCell
procedure duplicates existing bytes of memory, if your application needs to access a cell's data but does not need to manipulate the data, then it should use theLGetCellDataLocation
procedure to access cell data directly.
Listing 4-13 uses theLGetCellDataLocation
procedure to get a cell's data.Listing 4-13 Directly accessing a cell's data
PROCEDURE MyGetDirectAccessToCellData (VAR offset: Integer; VAR len: Integer; aCell: Cell; myList: ListHandle); BEGIN LGetCellDataLocation(offset, len, aCell, myList); END;TheLGetCellDataLocation
procedure simply returns in theoffset
andlen
parameters the offset and length of the appropriate cell's data within thecells
field of the list record.Listing 4-14 shows an application-defined procedure that uses
LGetCellDataLocation
in conjunction with theLSetCell
procedure
and theLAddRow
function to add a new string to a one-column, alphabetical text-only list. To compare two strings, the procedure uses the Text UtilitiesCompareText
function, which requires that data be specified by a pointer and length, thus makingLGetCellDataLocation
perfect for this purpose. For more information on theCompareText
function, see Inside Macintosh: Text.Listing 4-14 Adding an item to a one-column, alphabetical text list
PROCEDURE MyAddItemAlphabetically (myList: ListHandle; myString: Str255); VAR found: Boolean; {flag variable} myRows: Integer; {number of rows in list} currentRow: Integer; {row being examined} cellDataOffset, cellDataLength: Integer; {data being compared to string} aCell: Cell; {cell coordinates} BEGIN found := FALSE; {initialize flag variable} WITH myList^^.dataBounds DO myRows := bottom - top; {compute number of rows} currentRow := -1; {start before first row} WHILE NOT found DO BEGIN {try to insert before next row} currentRow := currentRow + 1; {move to next row} IF currentRow = myRows THEN {past the end of the list?} found := TRUE {insert string at this row} ELSE BEGIN SetPt(aCell, 0, currentRow); {prepare to check cell data} {find location of data} LGetCellDataLocation(cellDataOffset, cellDataLength, aCell, myList); HLockHi(Handle(myList^^.cells)); {lock list data in memory} IF CompareText(@myString[1], {skip length byte of string} Ptr(ORD4(myList^^.cells^) + cellDataOffset), Length(myString), cellDataLength, gitl2Hdl) = -1 THEN found := TRUE; {new string should precede } { this row's string} HUnlock(Handle(myList^^.cells)); {unlock list data} END; END; {add new row for string} currentRow := LAddRow(1, currentRow, myList); SetPt(aCell, 0, currentRow); {prepare to set cell data} {set data} LSetCell(@myString[1], Length(myString), aCell, myList); END;TheMyAddItemAlphabetically
procedure defined in Listing 4-14 simply compares a string to the text in each row of a list, until the string follows the row text alphabetically or until there are no more rows, that is, the row number (which is 0-based) is equal to the number of rows, in which case the string is appended to the end of the list.